<#include "/templates/taglibs.ftl" />
<#include "/templates/function.ftl" />
<!DOCTYPE html>
<html lang="zh-cn">
    <head>
        <meta charset="utf-8">
        <link rel="stylesheet" href="${contextPath}/assets/plugins/layui/css/layui.css" media="all" />
        <style>
            p {
                margin-bottom: 10px;
                font-size: 15px;
                color: #393D49;
                font-weight: 400;
                line-height: 1.8;
            }
            .site-content {
                background-color: #fff;
                padding: 20px 0 10px 20px;
            }
            .site-h1 {
                margin-bottom: 20px;
                line-height: 60px;
                padding-bottom: 10px;
                color: #393D49;
                border-bottom: 1px solid #eee;
                font-size: 28px;
                font-weight: 400;
            }
        </style>
    </head>
    <body>
        <div class="layui-fluid layui-container">
            <div class="layui-row site-content">
                <div class="layui-col-md12">
                    <h1 class="site-h1">Sharding-JDBC实现数据分片和读写分离</h1>
                    <p>Sharding-JDBC是ShardingSphere的第一个产品，也是ShardingSphere的前身。 它定位为轻量级Java框架，在Java的JDBC层提供的额外服务。</p>
                    <p>它使用客户端直连数据库，以jar包形式提供服务，无需额外部署和依赖，可理解为增强版的JDBC驱动，完全兼容JDBC和各种ORM框架。</p>
                    <br/>
                    <p>Sharding-JDBC的特性如下：</p>
                    <p>-适用于任何基于Java的ORM框架，如：JPA, Hibernate, Mybatis, Spring JDBC Template或直接使用JDBC。</p>
                    <p>-基于任何第三方的数据库连接池，如：DBCP, C3P0, BoneCP, Druid, HikariCP等。</p>
                    <p>-支持任意实现JDBC规范的数据库。目前支持MySQL，Oracle，SQLServer和PostgreSQL。</p>
                    
                    <p>Sharding-JDBC 包含了众多的功能模块包括数据分片，分布式主键，分布式事务，读写分离，弹性伸缩等等；作为一个数据库中间件最核心的功能当属数据分片了，Sharding-JDBC 提供了很多分库分表的策略和算法，接下来看看具体是如何使用这些策略的；</p>
                    
                    <fieldset class="layui-elem-field layui-field-title site-title">
                        <legend><a name="get">数据分片</a></legend> 
                    </fieldset>
                    <p>作为一个开发者我们希望中间件可以帮我们屏蔽底层的细节，让我们在面对分库分表的场景下，可以像使用单库单表一样简单；当然 ShardingSphere-JDBC 不会让大家失望，引入了分片数据源、逻辑表等概念</p>
                    <fieldset class="layui-elem-field layui-field-title site-title">
                        <legend><a name="get">分片数据源和逻辑表</a></legend> 
                    </fieldset>
                    <p>逻辑表：逻辑表是相对物理表来说的，通常做分表处理，某一张表会被分成多张表，比如订单表被拆分成 10 张表，分别是 t_order_0 到 t_order_9，而对应的逻辑表就是 t_order，对于开发者来说只需要使用逻辑表即可；</p>
                    <p>分片数据源：对于分库来说，通常会有多个库，或者说是多个数据源，所以这些数据源需要被统一管理起来，引入了分片数据源的概念，常见的 ShardingDataSource</p>
                    <br/>
                    <p>有了以上两个最基本的概念当然还不够，还需要分库分表策略算法帮助我们做路由处理；但是这两个概念可以让开发者有一种使用单库单表的感觉，就像下面这样一个简单的实例：</p>
                     <pre class="layui-code" lay-skin="notepad">
DataSource dataSource = ShardingDataSourceFactory.createDataSource(dataSourceMap, shardingRuleConfig,new Properties());
Connection conn = dataSource.getConnection();
String sql = "select id,user_id,order_id from t_order where order_id = 103";
PreparedStatement preparedStatement = conn.prepareStatement(sql);
ResultSet set = preparedStatement.executeQuery();
                     </pre>
                     <p>以上根据真实数据源列表，分库分表策略生成了一个抽象数据源，可以简单理解就是 ShardingDataSource；接下来的操作和我们使用 jdbc 操作正常的单库单表没有任何区别；</p>
                    <fieldset class="layui-elem-field layui-field-title site-title">
                        <legend><a name="get">分片策略算法</a></legend> 
                    </fieldset>
                    <p>Sharding-JDBC 在分片策略上分别引入了分片算法、分片策略两个概念，当然在分片的过程中分片键也是一个核心的概念；在此可以简单的理解分片策略 = 分片算法 + 分片键；至于为什么要这么设计，应该是 Sharding-JDBC 考虑更多的灵活性，把分片算法单独抽象出来，方便开发者扩展；</p>
                    <fieldset class="layui-elem-field layui-field-title site-title">
                        <legend><a name="get">分片算法</a></legend> 
                    </fieldset>
                    <p>提供了抽象分片算法类：ShardingAlgorithm，根据类型又分为：精确分片算法、区间分片算法、复合分片算法以及 Hint 分片算法</p>
                    <p>-精确分片算法：对应 PreciseShardingAlgorithm 类，主要用于处理 = 和 IN 的分片；</p>
                    <p>-区间分片算法：对应 RangeShardingAlgorithm 类，主要用于处理 BETWEEN AND, >, <, >=, <= 分片;</p>
                    <p>-复合分片算法：对应 ComplexKeysShardingAlgorithm 类，用于处理使用多键作为分片键进行分片的场景；</p>
                    <p>-Hint 分片算法：对应 HintShardingAlgorithm 类，用于处理使用 Hint 行分片的场景；</p>
                    <br/>
                    <p>以上所有的算法类都是接口类，具体实现交给开发者自己</p>
                     <fieldset class="layui-elem-field layui-field-title site-title">
                        <legend><a name="get">分片策略</a></legend> 
                    </fieldset>
                    <p>分片策略基本和上面的分片算法对应，包括：标准分片策略、复合分片策略、Hint 分片策略、内联分片策略、不分片策略；</p>
                    <p>标准分片策略：对应 StandardShardingStrategy 类，提供 PreciseShardingAlgorithm 和 RangeShardingAlgorithm 两个分片算法，PreciseShardingAlgorithm 是必须的，RangeShardingAlgorithm 可选的；</p>
                     <pre class="layui-code" lay-skin="notepad">
public final class StandardShardingStrategy implements ShardingStrategy {
    private final String shardingColumn;
    private final PreciseShardingAlgorithm preciseShardingAlgorithm;
    private final RangeShardingAlgorithm rangeShardingAlgorithm;
}
                     </pre>
                     <p>复合分片策略：对应 ComplexShardingStrategy 类，提供 ComplexKeysShardingAlgorithm 分片算法；</p>
                     <pre class="layui-code" lay-skin="notepad">
public final class ComplexShardingStrategy implements ShardingStrategy {
    @Getter
    private final Collection<String> shardingColumns;
    private final ComplexKeysShardingAlgorithm shardingAlgorithm;
}
                     </pre>
                     <p>Hint 分片策略：对应 HintShardingStrategy 类，通过 Hint 指定分片值而非从 SQL 中提取分片值的方式进行分片的策略；提供 HintShardingAlgorithm 分片算法</p>
                      <pre class="layui-code" lay-skin="notepad">
public final class HintShardingStrategy implements ShardingStrategy {
    @Getter
    private final Collection<String> shardingColumns;
    private final HintShardingAlgorithm shardingAlgorithm;
}
                      </pre>
                      <p>内联分片策略：对应 InlineShardingStrategy 类，没有提供分片算法，路由规则通过表达式来实现；</p>
                      <p>不分片策略：对应 NoneShardingStrategy 类，不分片策略；</p>
                      
                      
                      <fieldset class="layui-elem-field layui-field-title site-title">
                        <legend><a name="get">读写分离</a></legend> 
                    </fieldset>
                    <p>对于同一时刻有大量并发读操作和较少写操作类型的应用系统来说，将数据库拆分为主库和从库，主库负责处理事务性的增删改操作，从库负责处理查询操作，能够有效的避免由数据更新导致的行锁，使得整个系统的查询性能得到极大的改善。</p>
                </div>
            </div>
        </div>
    </body>
    <script type="text/javascript" src="${contextPath}/assets/plugins/layui/layui.js"></script>
    <script>
        layui.use('code', function(){ 
            layui.code({
                encode: true
            }); 
          });
    </script>
</html>